package org.meetunexpectedly.service.audit;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qiniu.storage.Region;
import org.meetunexpectedly.config.QiNiuConfig;
import org.meetunexpectedly.constant.AuditLabelMap;
import org.meetunexpectedly.constant.AuditStatus;
import org.meetunexpectedly.entity.json.*;
import org.meetunexpectedly.entity.response.AuditResponse;
import org.meetunexpectedly.entity.setting.Setting;
import org.meetunexpectedly.service.setting.SettingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.List;
import java.util.UUID;

/**
 * @Description: 审核服务抽象类，统一封装审核逻辑，并留给子类进行编排或者调用普通逻辑
 * @Author: pupil
 * @Date: 2024/08/13 下午 4:51
 */
@Service
public abstract class AbstractAuditService<T,R> implements AuditService<T,R> {

    @Autowired
    protected QiNiuConfig qiNiuConfig;

    @Autowired
    protected SettingService settingService;

    // 配置文件id
    protected final Integer settingId = 1;


    // 用于json序列化，设置忽略这些未知的字段
    protected ObjectMapper objectMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    protected static final String contentType = "application/json";

    /**
     * 审核
     *
     * @param scoreJsonList
     * @param bodyJson
     * @return
     */
    protected AuditResponse audit(List<ScoreJson> scoreJsonList, BodyJson bodyJson) {
        AuditResponse auditResponse = null;
        // 遍历三个审核规则：通过  人工  PASS
        for (ScoreJson scoreJson : scoreJsonList) {
            // 获取审核结果
            auditResponse = audit(scoreJson, bodyJson);
            // 如果为true，说明命中存在违规，提前返回
            if (auditResponse.getFlag()){
                return auditResponse;
            }
        }

        // 如果出来了说明审核的内容没分数 / 审核比例没调好(人员问题)
        // 比较suggest
        ScenesJson scenes = bodyJson.getResult().getResult().getScenes();
        if (endCheck(scenes)){
            auditResponse.setAuditStatus(AuditStatus.SUCCESS.num);
        }else {
            auditResponse.setAuditStatus(AuditStatus.PASS.num);
            auditResponse.setMsg("内容违规");
        }
        return auditResponse;
    }


    /**
     * 当前审核规则如果能匹配上也就是进入了if判断中,则需要获取违规信息
     * 如果走到末尾则说明没有匹配上
     *
     * @param scoreJson
     * @param bodyJson
     * @return
     */
    private AuditResponse audit(ScoreJson scoreJson, BodyJson bodyJson) {
        // 创建审核消息
        AuditResponse auditResponse = new AuditResponse();
        // 初始化为违规
        auditResponse.setFlag(true);
        // 设置审核状态：通过  人工  PASS
        auditResponse.setAuditStatus(scoreJson.getAuditStatus());

        // 审核力度
        Double minPulp = scoreJson.getMinPulp();
        Double maxPulp = scoreJson.getMaxPulp();
        Double minPolitician = scoreJson.getMinPolitician();
        Double maxPolitician = scoreJson.getMaxPolitician();
        Double minTerror = scoreJson.getMinTerror();
        Double maxTerror = scoreJson.getMaxTerror();


        // 所有都要比较，如果检测有问题直接返回, 这里使用策略模式
        // 检测政治
        if (!ObjectUtils.isEmpty(bodyJson.getPolitician())){
            // 命中
            if (bodyJson.checkViolation(bodyJson.getPolitician(),minPolitician,maxPolitician)){
                AuditResponse response = getInfo(bodyJson.getPolitician(), minPolitician, "group");
                auditResponse.setMsg(response.getMsg());
                // 判断是否违规
                if (response.getFlag()){
                    // 设置截帧的时间位置
                    auditResponse.setOffset(response.getOffset());
                    return auditResponse;
                }
            }
        }

        // 检测低俗
        if (!ObjectUtils.isEmpty(bodyJson.getPulp())){
            // 命中
            if (bodyJson.checkViolation(bodyJson.getPulp(),minPulp,maxPulp)){
                AuditResponse response = getInfo(bodyJson.getPulp(), minPulp, "normal");
                auditResponse.setMsg(response.getMsg());
                // 判断是否违规
                if (response.getFlag()){
                    // 设置截帧的时间位置
                    auditResponse.setOffset(response.getOffset());
                    return auditResponse;
                }
            }
        }

        // 检测反恐
        if (!ObjectUtils.isEmpty(bodyJson.getTerror())){
            // 命中
            if (bodyJson.checkViolation(bodyJson.getTerror(),minTerror,maxTerror)){
                AuditResponse response = getInfo(bodyJson.getTerror(), minTerror, "normal");
                auditResponse.setMsg(response.getMsg());
                if (response.getFlag()){
                    // 设置截帧的时间位置
                    auditResponse.setOffset(response.getOffset());
                    return auditResponse;
                }
            }
        }

        // 检测通过
        auditResponse.setMsg("正常");
        auditResponse.setFlag(false);
        return auditResponse;
    }

    /**
     * 返回对应规则的信息
     * @param cutsJsons 截帧审核结果
     * @param minPolitician 最小审核力度
     * @param key normal/group
     * @return
     */
    private AuditResponse getInfo(List<CutsJson> cutsJsons,Double minPolitician,String key){
        AuditResponse auditResponse = new AuditResponse();
        auditResponse.setFlag(false);

        String info = null;
        // 获取信息
        for (CutsJson cutsJson : cutsJsons) {
            for (DetailsJson detail : cutsJson.getDetails()) {
                // 只获取信息和offset
                if (detail.getScore() > minPolitician){
                    // 如果违规,则填充额外信息
                    if (!detail.getLabel().equals(key)){
                        info = AuditLabelMap.getInfo(detail.getLabel());
                        auditResponse.setMsg(info);
                        auditResponse.setOffset(cutsJson.getOffset());
                    }
                    auditResponse.setFlag(true); // 设置违规状态
                }
            }
        }

        // 七牛云审核通过，但不服务系统要求，则填充信息
        if (auditResponse.getFlag() && ObjectUtils.isEmpty(auditResponse.getMsg())){
            auditResponse.setMsg("该内容违反邂逅平台规则");
        }

        return auditResponse;
    }

    /**
     * 最后检查,可能没得分,检查suggestion
     * @param scenes 审核类型
     * @return
     */
    private boolean endCheck(ScenesJson scenes){
        TypeJson politician = scenes.getPolitician();
        TypeJson pulp = scenes.getPulp();
        TypeJson terror = scenes.getTerror();
        // 有一种类型出现建议：block(建议删除) 返回false
        if (terror.getSuggestion().equals("block") || politician.getSuggestion().equals("block") || pulp.getSuggestion().equals("block")){
            return false;
        }
        return true;
    }

    /**
     * 根据系统配置表查询是否需要审核
     * @return
     */
    protected Boolean isNeedAudit(){
        //  获取系统配置信息
        Setting setting = settingService.list(null).get(0);
        return setting.getAuditOpen();
    }

    /**
     * 附加UUID，进行资源防盗
     * @param url 资源
     * @return
     */
    protected String appendUUID(String url){
        //  获取系统配置信息
        Setting setting = settingService.list(null).get(0);

        // 判断是否开启回源鉴权
        if (setting.getAuth()){
            String uuid = UUID.randomUUID().toString();
            if (url.contains("?")){
                url = url+"&uuid="+uuid;
            }else {
                url = url+"?uuid="+uuid;
            }
            return url;
        }
        return url;
    }
}